#include "timer.h"
#include "main.h"
static Timer obj_timer = {
	.name = "obj"};
static Timer currentArrivalTimer = {0}; // 当前到时定时器
volatile uint32_t timer_Tick = 0;

uint32_t timer_GetTick(void)
{
	return timer_Tick;
}
void timer_IncTick(void)
{
	timer_Tick += 1;
}
int timer_count()
{
	return list_len(&obj_timer.timer_list);
}
Timer_State timer_state(Timer *timer)
{
	if (timer != 0)
	{
		return timer->Timer_RunState;
	}
	return Timer_INVALID;
}

Timer_State timer_create(Timer *timer, char *name, uint32_t interval,
						 Timer_WorkMode WorkMode,
						 void (*TimerCallBack)(void *param),
						 void *param)
{
	Timer *timer_t;
	if (timer == NULL)
		return Timer_INVALID;
	timer_t = timer_find(timer->name);
	if (timer_t != NULL)
	{
		timer_start(timer);
		return Timer_RUN;
	}
	memset(timer, 0, sizeof(Timer));
	strncpy(timer->name, name, TIMER_BSP_NAME_MAXLEN - 1);
	timer->interval = interval;
	timer->WorkMode = WorkMode;
	timer->Timer_RunState = Timer_READY;
	timer->TimerCallBack = TimerCallBack;
	timer->param = param;
	list_init(&timer->timer_list);
	list_insert_after(&obj_timer.timer_list, &timer->timer_list);

	return Timer_READY;
}
Timer *timer_find(char *name)
{
	Timer *timer = NULL;
	list *p = &obj_timer.timer_list;
	while (p->next != &obj_timer.timer_list)
	{
		timer = (Timer *)GET_DEVICE(p->next, Timer, timer_list);
		if (timer != NULL)
		{
			if (!strncmp(name, timer->name, TIMER_BSP_NAME_MAXLEN)) // 找到了对应的定时器
			{
				return timer;
			}
		}
		p = p->next;
	}
	return NULL;
}
void timer_start(Timer *timer)
{
	if (timer != 0)
	{
		if (timer_find(timer->name) == NULL)
			return;
		if (timer->Timer_RunState != Timer_INVALID)
		{
			timer->arrived_time_flag = 0;
			timer->run_time = 0;
//			timer->run_time_s = 0;
			timer->start_time = timer_GetTick();
//			timer->Next_Time = timer->start_time + timer->interval;
			timer->Timer_RunState = Timer_RUN;
		}
	}
}
void timer_stop(Timer *timer)
{
	if (timer != 0)
	{
		if (timer_find(timer->name) == NULL)
			return;
		if (timer->Timer_RunState != Timer_INVALID)
		{
			timer->Timer_RunState = Timer_STOP;
		}
	}
}

void timer_delete(Timer *timer)
{
	if (timer != 0)
	{
		if (timer_find(timer->name) == NULL)
			return;
		if (timer->Timer_RunState != Timer_INVALID)
		{
			timer->Timer_RunState = Timer_INVALID;
			list_remove(&timer->timer_list);
		}
	}
}
void timer_modify(Timer *timer, Timer_WorkMode WorkMode, uint32_t interval)
{
	if (timer != 0)
	{
		if (timer_find(timer->name) == NULL)
			return;
		if (timer->Timer_RunState != Timer_INVALID)
		{
			timer->interval = interval;
			timer->WorkMode = WorkMode;
			timer->arrived_time_flag = 0;
//			timer->run_time = 0;
//			timer->run_time_s = 0;
			timer->start_time = timer_GetTick();
//			timer->Next_Time = timer->start_time + timer->interval;
			// timer_t->Timer_RunState=Timer_RUN;
		}
	}
}
void timer_IrqHandle()
{
	uint32_t next_time = 0;
	Timer *timer = NULL;
	list *p = &obj_timer.timer_list;
	while (p->next != &obj_timer.timer_list)
	{
		timer = (Timer *)GET_DEVICE(p->next, Timer, timer_list);
		if (timer != NULL)
		{
			next_time = timer_GetTick();
			if (timer->Timer_RunState == Timer_RUN)
			{
//				timer->run_time = (uint32_t)(next_time - timer->start_time);
//				timer->run_time_s = timer->run_time / 1000;
				if ((uint32_t)(next_time - timer->start_time) >= timer->interval)
				{

					timer->arrived_time_flag = 1;
					if (timer->TimerCallBack != 0)
						timer->TimerCallBack(timer->param);
					if (timer->WorkMode == Timer_Single)
						timer->Timer_RunState = Timer_STOP;
					else
					{
						timer->start_time = timer_GetTick();
//						timer->Next_Time = timer->start_time + timer->interval;
					}
					memcpy(&currentArrivalTimer, timer, sizeof(Timer));
				}
			}
		}
		p = p->next;
	}
}
void delay_us(uint32_t us)
{
	uint32_t start, now, delta = 0, reload, us_tick;
	start = SysTick->VAL;
	reload = SysTick->LOAD;
	us_tick = SystemCoreClock / 1000000UL;
	do
	{
		now = SysTick->VAL;
		delta += start >= now ? start - now : reload + start - now;
	} while (delta < us_tick * us);
}
void delay_ms(uint16_t ms)
{
	for (uint32_t count = 0; count < ms; count++)
	{
		delay_us(1000);
	}
}
void timer_Polling(void)
{
	timer_IrqHandle();
}
extern void time_update(void);
void SysTick_Handler()
{
	timer_IncTick();
	timer_Polling();
	HAL_IncTick();
}
static int timer_autoInit(void)
{
	list_init(&obj_timer.timer_list);
	return 0;
}
BOARD_INIT(timer_autoInit);
